
const TRANSLATE_URI = 'http://translate.google.com/translate_tts?ie=UTF-8&tl=en&q=';

function ScreenAudio(){
    
    var context = this;
    this.port = chrome.extension.connect({
        name: "audio"
    });
    this.port.onMessage.addListener(function(data) {
        if( data.audio ){
            switch(data.audio){
                case 'end':
                    context.setSentence();
                break;
            }
        }
    });
    
    this.timeoutId = null;
    this.currentParagaph = null;
    this.currentSentence = 0;
    this.speaker = new AudioSpeaker();
}
ScreenAudio.prototype = {
    observe: function(){
        var context = this;
        $("*", document.body).live('mouseover', function(e){ 
            context.overAction.apply(context,[e]);
        });
    },
    overAction: function(e){
        var context = this;
        if (e.currentTarget === e.target) {
            chrome.extension.sendRequest({
                message: "isactive"
            }, function(response) {
                if (!response.active){
                    return;
                }
                context.doHover(e);
            });
        }
    },
    doHover: function(e){
        var context = this;
        $(e.target).addClass("screenreader-highlight");
        $(e.target).bind('mouseout', function(e){
            $(e.target).removeClass("screenreader-highlight");
            $(this).unbind(e);
            $(this).unbind('click');
        });
        $(e.target).unbind('click');
        $(e.target).bind('click',function(e){
            var clone = $($(this).clone());
            clone.find('script,style,img,object,embed').remove();
            var txt = jQuery.trim( clone.text() );
            txt = txt.replace(/[\n\r\t\s{2,}]+/gi,' ');
            if( txt == "" ){
                return;
            }
            context.currentSentence = 0;
            context.currentParagaph = context.prepareSenteces(txt);
            context.stop();
            context.setSentence();
        });
    },
    
    prepareText : function(txt){
        //
        // It's split all text paragraph to senteces by dot. 
        // First find any decimals in text and replace "." to word "point"
        // eg: ... 9.4% become 9 point 4 %
        //
        var replace = '$1 point $2 ';
        var pattern = new RegExp(/(\d)+\.(\d+)\s?/gi);
        var fullMatch = txt.match(pattern);
        replace = replace.replace(/\$0/, fullMatch);
        txt = txt.replace(pattern, replace);
        
        //replace sentences end mark to [ENDSENT] tag to restore later
        
        txt = txt.replace(/\.\s/gim, '[ENDSENT] ');
        txt = txt.replace(/\.$/gim, '[ENDSENT]');
        
        //replace all special characters
        txt = txt.replace(/\./gim, ' dot ');
        txt = txt.replace(/,/gim, ' comma ');
        txt = txt.replace(/!/gim, ' exclamation mark ');
        txt = txt.replace(/\?/gim, ' question mark ');
        txt = txt.replace(/"/gim, ' quotation mark ');
        txt = txt.replace(/"/gim, ' quotation mark ');
        txt = txt.replace(/\$/gim, ' dollear ');
        txt = txt.replace(/£/gim, ' pound ');
        
        txt = txt.replace(/\s?\[ENDSENT\]/g, '.');
        
        //add spaces to alle shortcut eg FBI -> F B I
        var r = new RegExp(/([A-Z]{2,})/g);
        var matches = txt.match(r);
        if( matches && matches.length > 0){
            for (var i = 0; i < matches.length; i++) {
                var replacement = matches[i].replace(/(\w)/g,'$1 ');
                txt = txt.replace(matches[i],  replacement );
            }
        }
        
        return txt;
    },
    
    prepareSenteces: function (txt){
        
        txt = this.prepareText(txt);
        
        var paragraph = txt.split(".");
    
        for( var i = 0; i < paragraph.length; i++ ){
            var sentence = paragraph[i];
            if( sentence.length > 100 ){ //line over 100 characters
                var j = 0, start = 0, first = true;
                do {
                    var length = 100;
                    var _tmp = sentence.substr(start, length);
                    _tmp = jQuery.trim(_tmp);
                
                    var r = new RegExp(/\s/gi);
                    var nextChar = sentence.substr(start+length, 1);
                    if( nextChar != "" && !r.test(nextChar) ){
                        var lengthPos = _tmp.lastIndexOf(" ");
                        lengthPos++;
                        if( lengthPos > 0 ){
                            length = lengthPos;
                            _tmp = sentence.substr(start, length);
                            _tmp = jQuery.trim(_tmp);
                        }
                    }
                    if( _tmp != "" ){
                        paragraph.splice(i+j, (first?1:0) ,_tmp);
                        first = false;
                    }
                    if( start > sentence.length ){
                        break;
                    }       
                    start+=length;
                    j++;
                } while(true);
            } else if( sentence == "" ){
                paragraph.splice(i, 1);
            }
        }
        return paragraph;
    },
    
    setSentence: function(){
        
        if (this.currentSentence >= this.currentParagaph.length){
            this.speaker.hide();
            this.stop();
            return;
        }
        var context = this;
        chrome.extension.sendRequest({
            message: "isactive"
        }, function(response) {
            if (response.active){
                var str = context.currentParagaph[context.currentSentence];
                if(!str){
                    context.currentSentence++;
                    context.setSentence();
                    return;
                }
                var url = TRANSLATE_URI+encodeURIComponent(str);
                context.play(url);
                context.currentSentence++;
                context.speaker.show();
            } else {
                context.speaker.hide();
                context.stop();
            }
        });
    },
    
    /**
     * Stop playing any audio.
     */
    stop: function(){
        this.port.postMessage({
            payload: "stop"
        });
    },
    /**
     * Play audio from URL
     */
    play: function(url){
        this.port.postMessage({
            payload: "play",
            url: url
        });
    }
}

$(document).ready(function(){
    var audio = new ScreenAudio();
    audio.observe();
});